C3 추락보호복 메시지 전송체계 연동

□ 시스템 구성

BLE

TCP/IP

센서보드

스마트폰

MQTT 서버

□ 메시지 전송

o (센서보드) 상태(1분마다) 및 추락(검출시) 메시지를 ‘변형 BASE64’로 인코딩한 후 BLE로 전송

- 메시지 형식

Q=n;TYPE;FALL,BAT,COUNT,DEVICE_ID;USER;PASS;SITE

- 메시지 예시

(상태) Q=0;1;0,100,001,AB12300000;user1;pass1;SF_HQ

(추락) Q=2;1;1,99,001,AB12300000;user1;pass1;xxx

o (스마트폰) 수신 메시지를 ‘변형 BASE64’로 디코딩한 후, PASS를 제거하고 ‘스마트폰 전화번호’/‘GPS 정보’를 첨부한 다음, ‘변형 BASE64’로 다시 인코딩해서 TCP/IP로 MQTT 서버에 전송

- 메시지 형식

Q=n;TYPE;FALL,BAT,COUNT,DEVICE_ID;USER;SITE;TELNO; LATITUDE,LONGITUDE

- 메시지 예시

Q=2;1;1,99,001,AB12300000;user1;xxx;01012345678;37.4140,127.0985

□ 메시지 전송체계 연동

o (휴랜) 스마트폰 앱에서 센서보드로부터 BLE로 수신한 메시지에 ‘스마트폰 전화번호’/‘GPS 정보’를 첨부한 다음, MQTT 서버로 전송(‘변형 BASE64’ 코딩 포함)

- MQTT 서버 : safewaredata.co.kr

* TCP 포트는 MQTT 디폴트 포트번호인 ‘1883’을 사용

- MQTT 서버로의 전송은 ‘org.eclipse.paho.client.mqttv3’의 MqttClient 클래스를 사용

* 참고 : https://www.eclipse.org/paho/index.php?page=downloads.php

o (세이프웨어) ‘변형 BASE64’ 및 ‘BLE 통신’ 등 세이프웨어 소스코드 3점을 휴랜에 제공

- 변형 BASE64 : Swbase64Code.java

- 데이터 모델 : mqttPublish_model.java

- BLE 통신 : UARTMulticonnectService.java

□ 주요 소스코드(UARTMulticonnectService.java)

import org.eclipse.paho.client.mqttv3.MqttClient;

import org.eclipse.paho.client.mqttv3.MqttConnectOptions;

import org.eclipse.paho.client.mqttv3.MqttException;

...

public class UARTMulticonnectService extends BleMulticonnectProfileService

implements UARTManagerCallbacks {

...

@Override

public void onDeviceConnected(@NonNull final BluetoothDevice device) {

super.onDeviceConnected(device);

try {

mMqttClients.put(device.getAddress(),

new MqttClient(String.format("tcp://%s", "safewaredata.co.kr"),

MqttClient.generateClientId(), null));

}

catch (MqttException e) { e.printStackTrace(); }

}

...

@Override

public void onDataReceived(@NonNull final BluetoothDevice device, final Data data) {

final Intent broadcast = new Intent(BROADCAST_UART_RX);

String rcvdata;

double gps_lat = 0;

double gps_long = 0;

try {

String trimStr = data.getStringValue(0);

trimStr = trimStr.trim();

trimStr = trimStr.replaceAll("(\r\n|\r|\n|\n\r)", "");

trimStr = trimStr.replaceAll(" ", "");

trimStr = trimStr.replace("\\n", "");

rcvdata = new String(mBase64.decode(trimStr.getBytes()));

Log.d("receiveData", rcvdata);

String msg = rcvdata;

gps_lat = mLocation.getLatitude();

gps_long = mLocation.getLongitude();

msg = msg.concat(String.format(";%s;%.04f,%.04f\n", mCtn, gps_lat, gps_long));

List<String> mDataList = new ArrayList<>();

StringBuilder sb = new StringBuilder(msg);

mDataList = Arrays.asList(sb.toString().split(";"));

mqttPublish_model mqttPublish_model = new mqttPublish_model(mDataList);

final UARTManager manager = (UARTManager) getBleManager(device);

broadcast.putExtra(EXTRA_DEVICE, manager.getBluetoothDevice());

broadcast.putExtra(EXTRA_DATA, mqttPublish_model.toString());

LocalBroadcastManager.getInstance(this).sendBroadcast(broadcast);

try {

MqttClient mqttClient;

if(!mMqttClients.isEmpty()) {

mqttClient = mMqttClients.get(device.getAddress());

if (mqttClient != null ) {

//비밀번호는 지움.

msg = msg.replace(mqttPublish_model.getPW() + ";", "");

attributePublish( mqttClient, mqttPublish_model, msg);

}

}

}

catch (Exception e){ e.printStackTrace(); }

}

catch (Exception e) { e.printStackTrace(); }

}

...

void attributePublish(MqttClient mqttClient,mqttPublish_model model,

String str_pub) {

try {

if(!mqttClient.isConnected()) {

MqttConnectOptions options = new MqttConnectOptions();

options.setCleanSession(true);

options.setUserName(model.getID());

options.setPassword(model.getPW().toCharArray());

mqttClient.connect(options);

}

if (mqttClient != null && mqttClient.isConnected()) {

//String Format 전송

mqttClient.publish(model.getTopic(),

str_pub.getBytes(), model.getQos().contains("2") ? 2 : 1, false);

}

}

catch (Exception e) { e.printStackTrace(); }

}

...

}

...